#![recursion_limit = "256"]
mod constants;
mod handlers;

use model_graph_common::utils::{read_bytes_from_pathbuf, rrg01_home_path};
use std::path::PathBuf;
use tauri::{
    http,
    plugin::{Builder, TauriPlugin},
    AppHandle, Manager, Runtime,
};

/// Initializes the plugin.
pub fn init<R: Runtime>() -> TauriPlugin<R> {
    Builder::new("mg-plugin")
        .invoke_handler(tauri::generate_handler![
            handlers::eval,
            handlers::window_set_url,
            handlers::install,
            handlers::local_install,
            handlers::uninstall,
            handlers::infor,
            handlers::upgrade,
            handlers::wasms
        ])
        .register_uri_scheme_protocol("rrg01", |_ctx, req| {
            let result = rrapp_protocol(req);
            match result {
                Ok(r) => r,
                Err(err) => {
                    tracing::error!("{}", err);
                    let body: Vec<u8> = vec![];
                    http::Response::builder().body(body).unwrap()
                }
            }
        })
        .setup(|app, plugin| {
            app.manage(handlers::ContextState::default());
            Ok(())
        })
        .build()
}

pub fn rrapp_protocol(request: http::Request<Vec<u8>>) -> anyhow::Result<http::Response<Vec<u8>>> {
    let url = request.uri().clone();
    let method = request.method().clone();
    let version = request.version().clone();
    let request_headers = request.headers().clone();
    // let body = request.body();

    let host_header_value: Vec<&str> = url
        .host()
        .ok_or(anyhow::anyhow!("获取host失败"))?
        .split(".")
        .collect();
    tracing::debug!("host:{:#?}", host_header_value);

    //[identifier].localhost/
    let plugin_id = host_header_value
        .get(0)
        .map_or(Err(::anyhow::anyhow!("URL中无法找到peer_id")), |v| {
            Ok(String::from(*v))
        })?;
    tracing::debug!("获取到Peer:[{}]", plugin_id);

    //plugin identifier为url中的
    let mut file_path = String::new();

    let url = url.path().to_string();
    let mut file_path = if url.contains("?") {
        let (first, _last) =
            url.split_at(url.find("?").map_or(Err(anyhow::anyhow!("")), |v| Ok(v))?);
        String::from(&first[1..])
    } else {
        String::from(&url[1..])
    };
    if file_path == "" {
        file_path = String::from("index.html");
    }
    tracing::debug!("plugin_id:{},请求地址:{}", plugin_id, file_path);

    //组装文件路径
    let file_path = get_rrapp_file_path(&plugin_id, &file_path)
        .map_err(|err| anyhow::anyhow!("获取文件路径失败:{}", err))?;

    //获取文件大小，如果太大，提示
    //app_cid 即为内容ID，为下载应用的路径中的一部分
    tracing::debug!("文件路径:{:?}", file_path);

    //获取文件内容
    let buf = read_bytes_from_pathbuf(&file_path)?;

    //获取mimetype
    let content_type = String::from(
        mime_guess::from_path(file_path)
            .first_or(mime::TEXT_PLAIN)
            .as_ref(),
    );

    http::Response::builder()
        .header("Origin", "*")
        // .mimetype(
        //     mime_guess::from_path(file_path)
        //         .first_or(mime::TEXT_PLAIN)
        //         .as_ref(),
        // )
        .header("Content-Type", content_type)
        .header("Content-Length", buf.len())
        .status(200)
        .body(buf)
        .map_err(|err| anyhow::anyhow!("{}", err))
}

pub fn get_rrapp_path(identifier: &String) -> anyhow::Result<PathBuf> {
    //静态文件路径
    let storage_path = rrg01_home_path()?
        .join(crate::constants::APP_ROOT_PATH)
        .join(identifier.replace(":", "_"));
    Ok(storage_path)
}

pub fn get_rrapp_file_path(identifier: &String, file_relative: &String) -> anyhow::Result<PathBuf> {
    //静态文件路径
    let file_path = rrg01_home_path()?
        .join(crate::constants::APP_ROOT_PATH)
        .join(identifier.replace(":", "_"))
        .join(file_relative);
    Ok(file_path)
}
